package com.qiongqi.datadir.service.impl;

import com.qiongqi.datadir.config.DataDirConfig;
import com.qiongqi.datadir.domain.Certificate;
import com.qiongqi.datadir.mapper.CertificateMapper;
import com.qiongqi.datadir.service.ICertificateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

import static com.qiongqi.datadir.consts.Constants.UPLOAD_PATH;
import static com.qiongqi.datadir.utils.security.PEMUtils.readPemFile;
import static com.qiongqi.datadir.utils.uuid.IdUtils.fastSimpleUUID;
import static java.util.Objects.nonNull;
import static org.apache.commons.collections4.IterableUtils.get;
import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class CertificateServiceImpl implements ICertificateService {

    @Autowired
    private DataDirConfig dataDirConfig;

    @Autowired
    private CertificateMapper certificateMapper;

    /**
     * 上传文件
     *
     * @param file
     * @return
     * @throws IOException
     */
    @Override
    public String uploadFile(MultipartFile file) throws IOException {
        String filePath = null;

        // 1. 生成年月日目录路径 (格式: yyyy/MM/dd)
        LocalDateTime now = LocalDateTime.now();
        String datePath = now.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        String storagePath = DataDirConfig.getProfile() + UPLOAD_PATH + "/" + datePath;

        // 2. 确保目标目录存在
        File targetDir = new File(storagePath);
        if (nonNull(targetDir) && !targetDir.exists()) {
            targetDir.mkdirs();  // 递归创建目录
        }

        if (nonNull(file)) {
            // 3. 生成带时间戳的文件名 (格式: 原文件名_yyyyMMddHHmmssSSS.扩展名)
            String originalName = file.getOriginalFilename();
            String fileExtension = "";
            if (containsIgnoreCase(originalName, ".")) {
                fileExtension = substringAfterLast(originalName, ".");
                originalName = substringBeforeLast(originalName, ".");
            }
            String timestamp = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
            String safeFileName = (isNotBlank(originalName) ? replace(originalName, " ", "_") : "file") // 删除空格
                    + "_" + timestamp + "." + fileExtension;

            // 4. 构建完整文件路径并保存
            File destFile = new File(targetDir, safeFileName);
            file.transferTo(destFile);  // 保存文件

            filePath = destFile.getAbsolutePath();
            int ret = saveOrUpdateCert(readPemFile(filePath));
            if(ret > 0){
                log.info("Inserted cert:{}, ret:{}", originalName, ret);
            }
        }
        return filePath;
    }

    /**
     * 保存或者修改凭证
     * @param cert
     * @return
     * @throws IOException
     */
    @Override
    public int saveOrUpdateCert(Certificate cert) throws IOException {
        int ret = -1;
        Instant currentTime = Instant.now();
        cert.setUpdateTime(currentTime);
        cert.setUpdateBy(dataDirConfig.getName());
        Certificate oldCert = selectOnlyCertificate();
        String certId = nonNull(oldCert) ? oldCert.getId() : null;
        if(isNotBlank(certId)){
            cert.setId(certId);
            ret = certificateMapper.updateCertificate(cert);
        }else{
            cert.setId(fastSimpleUUID());
            cert.setCreateTime(currentTime);
            cert.setCreateBy(dataDirConfig.getName());
            ret = certificateMapper.insertCertificate(cert);
        }
        return ret;
    }

    /**
     * 查看本节点凭证
     *
     * @return
     * @throws IOException
     */
    @Override
    public Certificate selectOnlyCertificate() throws IOException {
        String createBy = dataDirConfig.getName();
        Certificate cert = new Certificate();
        cert.setCreateBy(createBy);
        List<Certificate> certs = certificateMapper.selectCertificateList(cert);
        return isNotEmpty(certs) ? get(certs, 0) : null;
    }
}
